﻿using System;
using System.Reflection;
using TFramework.ECS.System.Handler;
using VContainer.Unity;

namespace TFramework.ECS.System.Manager
{
    public class SystemLookup : IStartable, ITickable, ISystemLookup
    {
        public SetupSystemHandler setupSystemHandler;
        public TeardownSystemHandler teardownSystemHandler;
        public UpdateSystemHandler updateSystemHandler;

        public SystemLookup(SetupSystemHandler setupSystemHandler, TeardownSystemHandler teardownSystemHandler, UpdateSystemHandler updateSystemHandler)
        {
            this.setupSystemHandler = setupSystemHandler;
            this.teardownSystemHandler = teardownSystemHandler;
            this.updateSystemHandler = updateSystemHandler;
        }

        public void Start()
        {
            Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var assembly in assemblys)
            {
                foreach (var item in assembly.GetTypes())
                {
                    var result = item.GetInterface(typeof(ISystem).ToString());
                    if (null == result)
                        continue;
                    if (item.IsClass)
                    {
                        var system = assembly.CreateInstance(item.ToString()) as ISystem;
                        VContainerManager.Instance.LifetimeScope.Container.Inject(system);
                        if (setupSystemHandler.CanHandleSystem(system))
                            setupSystemHandler.SetupSystem(system);
                        if (teardownSystemHandler.CanHandleSystem(system))
                            teardownSystemHandler.SetupSystem(system);
                        if (updateSystemHandler.CanHandleSystem(system))
                            updateSystemHandler.SetupSystem(system);
                    }
                }
            }
        }


        public void Tick()
        {
            foreach (var updateSystem in updateSystemHandler._updateSystems)
            {
                updateSystem.Value.OnNext(updateSystem.Key);
            }
        }
    }
}
